#include "XMLInterpreter.h"

XMLInterpreter::XMLInterpreter(){

}

void XMLInterpreter::setParams(AHP *ahp, float**distancias){
    this->ahp=ahp;
    this->distancias=distancias;
}

float ** XMLInterpreter::getDistancias(){
    return this->distancias;
}

void XMLInterpreter::saveFile(string filePath){
    ofstream file(filePath.c_str());

    if(file.is_open()){
        //------------VARIABLES---------------
        list<string> alternativas=this->ahp->getAlternativas();
        string * vectorAlternativas=new string[alternativas.size()];
        int i=0;
        for(list<string>::iterator it=alternativas.begin();it!=alternativas.end();it++){
            vectorAlternativas[i]=*it;
            i++;
        }
        list<string> criterios=this->ahp->getCriterios();

        file << "<proyecto>" << endl;
        //------------ALTERNATIVAS---------------
        file << "   <alternativas>" << endl;

        for(list<string>::iterator it=alternativas.begin();it!=alternativas.end();it++){
            file << "      <alternativa>" << endl;
            file << "           " << *it << endl;
            file << "      </alternativa>" << endl;
        }
        file << "   </alternativas>" << endl;

        //------------CRITERIOS---------------
        file << "   <criterios>" << endl;
        for(list<string>::iterator it=criterios.begin();it!=criterios.end();it++){
            file << "      <criterio>" << endl;
            file << "           " << *it << endl;
            file << "      </criterio>" << endl;
        }
        file << "   </criterios>" << endl;

        //------------CAMINOS---------------
        file << "   <caminos>" << endl;
        for(int i=0;i<alternativas.size();i++){
            for(int j=i+1;j<alternativas.size();j++){
                if(this->distancias[i][j]!=_INF_){
                    file << "      <camino>" << endl;

                    file << "          <origen>" << endl;
                    file << "               " << vectorAlternativas[i] << endl;
                    file << "          </origen>" << endl;

                    file << "          <destino>" << endl;
                    file << "               " << vectorAlternativas[j] << endl;
                    file << "          </destino>" << endl;

                    file << "          <distancia>" << endl;
                    file << "               " << QString::number(this->distancias[i][j]).toStdString() << endl;
                    file << "          </distancia>" << endl;

                    file << "      </camino>" << endl;
                }
            }
        }
        file << "   </caminos>" << endl;

        //------------CRITERIOS---------------
        file << "   <comparaciones>" << endl;

        //------------CRITERIOS ALTERNATIVAS---------------
        for(list<string>::iterator itC=criterios.begin();itC!=criterios.end();itC++){
            for(list<string>::iterator itA1=alternativas.begin();itA1!=alternativas.end();itA1++){
                for(list<string>::iterator itA2=alternativas.begin();itA2!=alternativas.end();itA2++){
                    if(this->ahp->getComparacionAlternativas(*itC,*itA1,*itA2)>1){
                        file << "      <comparacionA>" << endl;

                        file << "          <criterio>" << endl;
                        file << "               " << *itC << endl;
                        file << "          </criterio>" << endl;

                        file << "          <alternativa1>" << endl;
                        file << "               " << *itA1 << endl;
                        file << "          </alternativa1>" << endl;

                        file << "          <alternativa2>" << endl;
                        file << "               " << *itA2 << endl;
                        file << "          </alternativa2>" << endl;

                        file << "          <valor>" << endl;
                        file << "               " << this->ahp->getComparacionAlternativas(*itC,*itA1,*itA2) << endl;
                        file << "          </valor>" << endl;

                        file << "      </comparacionA>" << endl;
                    }
                }
            }
        }

        //------------CRITERIOS CRITERIOS---------------
        for(list<string>::iterator itC1=criterios.begin();itC1!=criterios.end();itC1++){
            for(list<string>::iterator itC2=criterios.begin();itC2!=criterios.end();itC2++){
                if(this->ahp->getComparacionCriterios(*itC1,*itC2)>1){
                    file << "      <comparacionC>" << endl;

                    file << "          <criterio1>" << endl;
                    file << "               " << *itC1 << endl;
                    file << "          </criterio1>" << endl;

                    file << "          <criterio2>" << endl;
                    file << "               " << *itC2 << endl;
                    file << "          </criterio2>" << endl;

                    file << "          <valor>" << endl;
                    file << "               " << this->ahp->getComparacionCriterios(*itC1,*itC2) << endl;
                    file << "          </valor>" << endl;

                    file << "      </comparacionC>" << endl;
                }
            }
        }
        file << "   </comparaciones>" << endl;
        file << "</proyecto>" << endl;

        file.close();
    }
}


void XMLInterpreter::loadFile(string filePath){
    this->ahp->clear();

    ifstream file(filePath.c_str());

    if(file.is_open()){
        string lectura;
        file >> lectura;
        if(lectura=="<proyecto>"){
            while(lectura!="</proyecto>"){
                if(lectura=="<alternativas>"){
                    this->leerAlternativas(file);
                }
                if(lectura=="<criterios>"){
                    this->leerCriterios(file);
                }
                if(lectura=="<caminos>"){
                    this->leerCaminos(file);
                }
                if(lectura=="<comparaciones>"){
                    this->leerComparaciones(file);
                }
                file >> lectura;
            }
        }
    }
}

void XMLInterpreter::leerAlternativas(ifstream &file){
    string lectura;
    file >> lectura;
    while(lectura!="</alternativas>"){
        if(lectura=="<alternativa>"){
            file >> lectura;
            this->ahp->addAlternativa(lectura);
        }
        file >> lectura;
    }

    this->distancias=new float*[this->ahp->countAlternativas()];
    for(int i=0;i<this->ahp->countAlternativas();i++){
        this->distancias[i]=new float[this->ahp->countAlternativas()];
        for(int j=0;j<this->ahp->countAlternativas();j++){
            this->distancias[i][j]=_INF_; //incializar matriz de distancias absolutas entre alternativas con valor infinito
        }
    }
}

void XMLInterpreter::leerCriterios(ifstream &file){
    string lectura;
    file >> lectura;
    while(lectura!="</criterios>"){
        if(lectura=="<criterio>"){
            file >> lectura;
            this->ahp->addCriterio(lectura);
        }
        file >> lectura;
    }
}

void XMLInterpreter::leerCaminos(ifstream &file){
    string lectura;
    file >> lectura;
    while(lectura!="</caminos>"){
        if(lectura=="<camino>"){
            this->leerCamino(file);
        }
        file >> lectura;
    }
}

void XMLInterpreter::leerCamino(ifstream &file){
    string Origen;
    string Destino;
    string Distancia;
    string lectura;
    file >> lectura;
    while(lectura!="</camino>"){
        if(lectura=="<origen>"){
            file >> Origen;
        }
        if(lectura=="<destino>"){
            file >> Destino;
        }
        if(lectura=="<distancia>"){
            file >> Distancia;
        }
        file >> lectura;
    }

    list<string> alternativas=this->ahp->getAlternativas();
    int OrigenIndex;
    int DestinoIndex;
    float DistanciaFloat;
    int i=0;
    for(list<string>::iterator it=alternativas.begin();it!=alternativas.end();it++){
        if(Origen==*it){
            OrigenIndex=i;
        }
        if(Destino==*it){
            DestinoIndex=i;
        }
        i++;
    }

    DistanciaFloat=QString::fromStdString(Distancia).toFloat();

    this->distancias[OrigenIndex][DestinoIndex]=DistanciaFloat;
    this->distancias[DestinoIndex][OrigenIndex]=DistanciaFloat;
}

void XMLInterpreter::leerComparaciones(ifstream &file){
    string lectura;
    file >> lectura;
    while(lectura!="</comparaciones>"){
        if(lectura=="<comparacionA>"){
            this->leerComparacionA(file);
        }
        if(lectura=="<comparacionC>"){
            this->leerComparacionC(file);
        }
        file >> lectura;
    }
}

void XMLInterpreter::leerComparacionA(ifstream &file){
    string Criterio;
    string Alternativa1;
    string Alternativa2;
    float Valor;
    string lectura;
    file >> lectura;
    while(lectura!="</comparacionA>"){
        if(lectura=="<criterio>"){
            file >> lectura;
            Criterio=lectura;
        }
        if(lectura=="<alternativa1>"){
            file >> lectura;
            Alternativa1=lectura;
        }
        if(lectura=="<alternativa2>"){
            file >> lectura;
            Alternativa2=lectura;
        }
        if(lectura=="<valor>"){
            file >> lectura;
            Valor=QString::fromStdString(lectura).toFloat();
        }
        file >> lectura;
    }

    this->ahp->setComparacionAlternativas(Criterio,Alternativa1,Alternativa2,Valor);
}

void XMLInterpreter::leerComparacionC(ifstream &file){
    string Criterio1;
    string Criterio2;
    float Valor;
    string lectura;
    file >> lectura;
    while(lectura!="</comparacionC>"){
        if(lectura=="<criterio1>"){
            file >> lectura;
            Criterio1=lectura;
        }
        if(lectura=="<criterio2>"){
            file >> lectura;
            Criterio2=lectura;
        }
        if(lectura=="<valor>"){
            file >> lectura;
            Valor=QString::fromStdString(lectura).toFloat();
        }
        file >> lectura;
    }

    this->ahp->setComparacionCriterios(Criterio1,Criterio2,Valor);
}


